﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SZEWBridgeFormInterface;
using SZEWBridgeNet.SZEWBridgeModel;
using ATEC;
using System.Security.Cryptography;
using ATEC.GeometryNET;
using ATEC.ATDataCoreNET;
using SZEWNet.SZEWCoreNet;

namespace SZEWBridgeUtilExample
{
    public partial class BridgeModelTestForm : Form
    {
        public BridgeModelTestForm()
        {
            InitializeComponent();
        }

        private void AssembleSubstructure(string categoryName, string templateName, ATEC.GeometryNET.XPoint3d placePt)
        {
            SzewBridgeSubStructureModelMsg msg = new SzewBridgeSubStructureModelMsg();

            //设置建模参数
            SzewBridgeSubStructureModelMsg.ModelParameter parameters = msg.parameters;
            parameters.nPierNo = 0;
            parameters.sCategoryName = categoryName;
            parameters.sTemplateName = templateName;
            parameters.dCrossSlope = 2;
            parameters.dLongiSlope = 2;
            string templatePath = GetCurProjectModelLibPath();//建模族库
            if (!File.Exists(templatePath))
            {
                MessageBox.Show(string.Format("{0}组装失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!", categoryName));
                return;
            }

            XVector3d xDir = new XVector3d(1, 0, 0);
            xDir.NormalizeInPlace();
            XVector3d yDir = XVector3d.UnitZ.CrossProduct(xDir);
            XMatrix3d rotMatrix = XMatrix3d.FromColumns(xDir, yDir, XVector3d.UnitZ);
            parameters.transform = XTransform3d.FromMatrixAndTranslation(rotMatrix, placePt);

            //调用接口，创建下部结构
            SzewBridgeTransitionSlabMsg transitionSlabMsg = new SzewBridgeTransitionSlabMsg();
            transitionSlabMsg.bSetted = true;
            transitionSlabMsg.eSettingKind = TransitionSlabSettingKind.Yes_Auto;
            SzewBridgeConicalSlopeMsg conicalSlopeMsg = new SzewBridgeConicalSlopeMsg();
            conicalSlopeMsg.sTemplateName = "示例1";
            SZEWBridgeModelUtil.CreateSubStructureModel(out msg, transitionSlabMsg, conicalSlopeMsg);
        }

        private void button_substructureAssemble_Click(object sender, EventArgs e)
        {
            //桥墩
            AssembleSubstructure("柱式墩组合构件", "变截面方墩--套筒", ATEC.GeometryNET.XPoint3d.FromXYZ(0, 0, 0));

            //柱式台
            AssembleSubstructure("柱式台下部结构", "示例1", ATEC.GeometryNET.XPoint3d.FromXYZ(0, 100000, 0));

            //肋板台
            AssembleSubstructure("肋板台下部结构", "示例1", ATEC.GeometryNET.XPoint3d.FromXYZ(0, 200000, 0));

            //轻型桥台
            AssembleSubstructure("轻型桥台下部结构", "示例1", ATEC.GeometryNET.XPoint3d.FromXYZ(0, 300000, 0));
        }

        private bool CreateConcreteGuardrailParams(ref SzewBridgeGuardrailModelMsg modelMsg, GuardrailTypeEnum guardrailTypeEnum, XTransform3d trans, bool bOutputMessage = false)
        {
            //构造混凝土护栏参数
            string templatePath = GetCurProjectModelLibPath();//建模族库
            if (!File.Exists(templatePath) && bOutputMessage)
            {
                MessageBox.Show("查找混凝土护栏族库路径失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
            }

            if (!File.Exists(templatePath))
            {
                return false;
            }

            List<ATEC.GeometryNET.XPoint3d> loftPlacePts = new List<ATEC.GeometryNET.XPoint3d> { ATEC.GeometryNET.XPoint3d.Zero, ATEC.GeometryNET.XPoint3d.FromXYZ(0, 50000, 0), ATEC.GeometryNET.XPoint3d.FromXYZ(0, 100000, 0) };     
            trans.MultiplyArrayInPlace(loftPlacePts);

            List<XAngle> loftPlaceSkewAngle = new List<XAngle>();
            for (int i = 0; i < loftPlacePts.Count; ++i)
            {
                loftPlaceSkewAngle.Add(XAngle.FromDegrees(90));
            }

            List<ATEC.GeometryNET.XPoint3d> loftPlaceTan = new List<ATEC.GeometryNET.XPoint3d>();
            for (int i = 0; i < loftPlacePts.Count; ++i)
            {
                loftPlaceTan.Add(ATEC.GeometryNET.XPoint3d.FromXYZ(0, 1, 0));
            }

            List<double> loftPlaceSlope = new List<double>();
            for (int i = 0; i < loftPlacePts.Count; ++i)
            {
                loftPlaceSlope.Add(2);
            }

            modelMsg.parameters.eGuardrailType = guardrailTypeEnum;
            modelMsg.parameters.sceneRef = ATEC.ATCore.Session.Entity.GetActiveATScenesRef();

            //左侧护栏参数
            modelMsg.parameters.leftConcreteGuardrailParams.loftPlacePts = loftPlacePts;
            modelMsg.parameters.leftConcreteGuardrailParams.loftPlaceSkewAngle = loftPlaceSkewAngle;
            modelMsg.parameters.leftConcreteGuardrailParams.loftPlaceSlope = loftPlaceSlope;
            modelMsg.parameters.leftConcreteGuardrailParams.loftPlaceTan = loftPlaceTan;
            modelMsg.parameters.leftConcreteGuardrailParams.sTemplateName = "示例1";

            //右侧护栏参数
            List<ATEC.GeometryNET.XPoint3d> rightLoftPlacePts = new List<ATEC.GeometryNET.XPoint3d>(loftPlacePts);
            XTransform3d rightGuardrailTrans = XTransform3d.FromTranslation(50000, 0, 0);//右侧护栏相对于左侧护栏的偏移
            rightGuardrailTrans.MultiplyArrayInPlace(rightLoftPlacePts);
            modelMsg.parameters.rightConcreteGuardrailParams.loftPlacePts = rightLoftPlacePts;
            modelMsg.parameters.rightConcreteGuardrailParams.loftPlaceSkewAngle = loftPlaceSkewAngle;
            modelMsg.parameters.rightConcreteGuardrailParams.loftPlaceSlope = loftPlaceSlope;
            modelMsg.parameters.rightConcreteGuardrailParams.loftPlaceTan = loftPlaceTan;
            modelMsg.parameters.rightConcreteGuardrailParams.sTemplateName = "示例1";

            //打印布置线
            BasicCurve basicCurve = BasicCurve.CreateLineString(loftPlacePts);
            ATEC.ATDataCoreNET.ATObjects.ATObject curveSetObj = ATEC.ATDataCoreNET.ATObjects.GeometryToATObject.ToObject
                (modelMsg.parameters.sceneRef.GetATScene(), basicCurve, null);
            curveSetObj.AddToScene();

            basicCurve = BasicCurve.CreateLineString(rightLoftPlacePts);
            curveSetObj = ATEC.ATDataCoreNET.ATObjects.GeometryToATObject.ToObject
                (modelMsg.parameters.sceneRef.GetATScene(), basicCurve, null);
            curveSetObj.AddToScene();

            return true;
        }

        private void AssembleGuardrailStructure_FTypeConcrete()
        {
            SzewBridgeGuardrailModelMsg modelMsg = new SzewBridgeGuardrailModelMsg();
            if (!CreateConcreteGuardrailParams(ref modelMsg, GuardrailTypeEnum.GUARDRAIL_TYPE_FCONCRETE, XTransform3d.FromTranslation(0, 0, 0), true))
                return;

            SZEWBridgeModelUtil.CreateGuardrailModel(out modelMsg);
        }

        private void AssembleGuardrailStructure_PlanterTypeConcrete()
        {
            SzewBridgeGuardrailModelMsg modelMsg = new SzewBridgeGuardrailModelMsg();
            if (!CreateConcreteGuardrailParams(ref modelMsg, GuardrailTypeEnum.GUARDRAIL_TYPE_PLANTERCONCRETE, XTransform3d.FromTranslation(100000, 0, 0)))
                return;

            SZEWBridgeModelUtil.CreateGuardrailModel(out modelMsg);
        }

        private void AssembleGuardrailStructure_CustomizedTypeConcrete()
        {
            SzewBridgeGuardrailModelMsg modelMsg = new SzewBridgeGuardrailModelMsg();
            if (!CreateConcreteGuardrailParams(ref modelMsg, GuardrailTypeEnum.GUARDRAIL_TYPE_CUSTOMIZED, XTransform3d.FromTranslation(200000, 0, 0)))
                return;

            SZEWBridgeModelUtil.CreateGuardrailModel(out modelMsg);
        }

        private void AssembleGuardrailStructure_Steel()
        {
            //钢护栏参数
            SzewBridgeGuardrailModelMsg modelMsg = new SzewBridgeGuardrailModelMsg();
            List<ATEC.GeometryNET.XPoint3d> leftLoftPlacePts = new List<ATEC.GeometryNET.XPoint3d> 
            { ATEC.GeometryNET.XPoint3d.FromXYZ(300000, 0, 0), ATEC.GeometryNET.XPoint3d.FromXYZ(300000, 50000, 0), ATEC.GeometryNET.XPoint3d.FromXYZ(300000, 100000, 0) };
            BasicCurve leftPath = BasicCurve.CreateLineString(leftLoftPlacePts);
            List<ATEC.GeometryNET.XPoint3d> rightLoftPlacePts = new List<ATEC.GeometryNET.XPoint3d> 
            { ATEC.GeometryNET.XPoint3d.FromXYZ(350000, 0, 0), ATEC.GeometryNET.XPoint3d.FromXYZ(350000, 50000, 0), ATEC.GeometryNET.XPoint3d.FromXYZ(350000, 100000, 0) };
            BasicCurve rightPath = BasicCurve.CreateLineString(rightLoftPlacePts);
            modelMsg.parameters.eGuardrailType = GuardrailTypeEnum.GUARDRAIL_TYPE_STEEL;
            modelMsg.parameters.sceneRef = ATEC.ATCore.Session.Entity.GetActiveATScenesRef();
            modelMsg.parameters.steelGuardrailParams.leftPath = leftPath;
            modelMsg.parameters.steelGuardrailParams.rightPath = rightPath;
            //注：钢护栏默认db所在路径为软件安装路径/SZEWBridge/Guardrails/护栏Mesh.db

            //打印布置线
            ATEC.ATDataCoreNET.ATObjects.ATObject curveSetObj = ATEC.ATDataCoreNET.ATObjects.GeometryToATObject.ToObject
                (modelMsg.parameters.sceneRef.GetATScene(), leftPath, null);
            curveSetObj.AddToScene();

            curveSetObj = ATEC.ATDataCoreNET.ATObjects.GeometryToATObject.ToObject
                (modelMsg.parameters.sceneRef.GetATScene(), rightPath, null);
            curveSetObj.AddToScene();

            SZEWBridgeModelUtil.CreateGuardrailModel(out modelMsg);
        }

        private void button_guardrailAssemble_Click(object sender, EventArgs e)
        {
            //F型护栏
            AssembleGuardrailStructure_FTypeConcrete();

            //带花槽护栏
            AssembleGuardrailStructure_PlanterTypeConcrete();

            //自定义护栏
            AssembleGuardrailStructure_CustomizedTypeConcrete();

            //钢护栏
            AssembleGuardrailStructure_Steel();
        }

        private void button_supportAssemble_Click(object sender, EventArgs e)
        {
            SzewBridgeBrace3PiecesModelMsg modelMsg = new SzewBridgeBrace3PiecesModelMsg();
            SzewBridgeBrace3PiecesModelMsg.ModelParameter modelParameter = modelMsg.parameters;

            string templatePath = GetCurProjectModelLibPath();//建模族库路径
            string productLibPath = GetCurProjectProductLibPath();//建模族库路径
            if (!File.Exists(templatePath) || !File.Exists(productLibPath))
            {
                MessageBox.Show("支撑组装失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
                return;
            }

            modelParameter.sceneRef = ATEC.ATCore.Session.Entity.GetActiveATScenesRef();
            modelParameter.sTemplateFilePath = templatePath;
            modelParameter.sProductLibPath = productLibPath;

            //楔形块参数
            modelParameter.dCrossSlopeOfWedgeTop = 0;
            modelParameter.dTopLongitudinalSlopeOfWedgeTop = 2;
            modelParameter.sTemplateNameOfWedge = "示例1";

            //支座参数
            modelParameter.eBearingType = BearingType.Rectangular_Rubber_Bearing;
            modelParameter.sTemplateNameOfBearing = "矩形橡胶支座1";

            //垫石参数
            modelParameter.dSlopeOfPadstoneBtm = 2;
            modelParameter.sTemplateNameOfPadstone = "示例1";

            //坐标系变换
            XMatrix3d rot = XMatrix3d.Identity;
            ATEC.GeometryNET.XPoint3d pt = ATEC.GeometryNET.XPoint3d.Zero;
            modelParameter.transform = XTransform3d.FromMatrixAndFixedPoint(rot, pt);
            modelParameter.skewAngle = XAngle.FromDegrees(90);

            //创建支撑三件套
            SZEWBridgeModelUtil.CreateBrace3PiecesModel(out modelMsg);
        }

        private void button_openPierTemplate_Click(object sender, EventArgs e)
        {
            //设置族库路径，若当前项目不是桥梁项目，请自行传入族库路径
            FilePathContext pathContext = new FilePathContext();
            pathContext.TemplateLibPath = GetCurProjectModelLibPath();
            pathContext.ProductLibPath = GetCurProjectProductLibPath();
            pathContext.MaterialLibPath = GetCurProjectMaterialLibPath();
            if (!File.Exists(pathContext.TemplateLibPath) || !File.Exists(pathContext.ProductLibPath) ||
                !File.Exists(pathContext.MaterialLibPath))
            { 
                MessageBox.Show("打开桥墩族库失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
                return;
            }

            TemplateContext templateContext = new TemplateContext();
            IModelTemplate.OpenModelTemplate(out templateContext, pathContext, StructureType.Pier);
        }

        private void button_openAbutmentTemplate_Click(object sender, EventArgs e)
        {
            //设置族库路径，若当前项目不是桥梁项目，请自行传入族库路径
            FilePathContext pathContext = new FilePathContext();
            pathContext.TemplateLibPath = GetCurProjectModelLibPath();
            pathContext.ProductLibPath = GetCurProjectProductLibPath();
            pathContext.MaterialLibPath = GetCurProjectMaterialLibPath();
            if (!File.Exists(pathContext.TemplateLibPath) || !File.Exists(pathContext.ProductLibPath) ||
                !File.Exists(pathContext.MaterialLibPath))
            {
                MessageBox.Show("打开桥台族库失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
                return;
            }

            TemplateContext templateContext = new TemplateContext();
            IModelTemplate.OpenModelTemplate(out templateContext, pathContext, StructureType.Abutment);
        }

        private void button_queryPierTemplateNames_Click(object sender, EventArgs e)
        {
            //设置族库路径，若当前项目不是桥梁项目，请自行传入族库路径
            FilePathContext pathContext = new FilePathContext();
            pathContext.TemplateLibPath = GetCurProjectModelLibPath();
            if (!File.Exists(pathContext.TemplateLibPath))
            {
                MessageBox.Show("打开桥墩族库失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
                return;
            }

            //查询桥墩模板名称
            List<string> templateNameList = new List<string>();
            IModelTemplate.QueryTemplateNameByCategoryName(ref templateNameList, CategoryType.ColumnPier, pathContext);
            string outputMessage = "";
            for (int i = 0; i < templateNameList.Count; ++i)
            {
                string templateName = templateNameList[i];
                templateName = templateName.PadRight(30);
                outputMessage += templateName;
                if(i % 2 == 1)
                    outputMessage += "\n";
            }

            System.Windows.Forms.MessageBox.Show(outputMessage);
        }

        private void button_openBearingProductLib_Click(object sender, EventArgs e)
        {
            //设置族库路径，若当前项目不是桥梁项目，请自行传入族库路径
            FilePathContext pathContext = new FilePathContext();
            pathContext.ProductLibPath = GetCurProjectProductLibPath();
            if (!File.Exists(pathContext.ProductLibPath))
            {
                MessageBox.Show("打开支座产品库失败，请点击桥梁BIM->新建工程 新建桥梁项目或传入族库路径!");
                return;
            }

            TemplateContext templateContext = new TemplateContext();
            IModelTemplate.OpenProductLibTemplate(out templateContext, "支座", pathContext);
        }

        //获取当前文件产品库路径
        private static string GetCurProjectProductLibPath()
        {
            FileInfo fileInfo = new FileInfo(ATEC.ATCore.Session.Entity.GetActiveFileName());
            return Path.Combine(fileInfo.DirectoryName, "建模", "ProductLib.xml");
        }

        //获取当前文件材料库路径
        private static string GetCurProjectMaterialLibPath()
        {
            FileInfo fileInfo = new FileInfo(ATEC.ATCore.Session.Entity.GetActiveFileName());
            return Path.Combine(fileInfo.DirectoryName, "建模", "MaterialLib.xml");
        }

        //获取当前文件路径建模族库路径
        private static string GetCurProjectModelLibPath()
        {
            FileInfo fileInfo = new FileInfo(ATEC.ATCore.Session.Entity.GetActiveFileName());
            return Path.Combine(fileInfo.DirectoryName, "建模", "template.xml");
        }
    }
}
